import { ref } from 'vue';
import { defineStore } from 'pinia';
import { LocationQuery, RouteLocationNormalized } from 'vue-router';

export interface TagView {
  path: string;
  fullPath: string;
  name?: string;
  affix: boolean;
  noCache: boolean;
  query?: LocationQuery;
  title?: string;
  icon?: string;
}

// setup
export const useTagsViewStore = defineStore('tagsView', () => {
  // state
  const visitedViews = ref<TagView[]>([]);
  const cachedViews = ref<string[]>([]);

  function createTagView(view: RouteLocationNormalized) {
    return {
      path: view.path,
      fullPath: view.fullPath,
      name: view.name as string,
      title: (view.meta?.title || 'no-name') as string,
      query: view.query,
      icon: view.meta?.icon as string | undefined,
      affix: view.meta?.affix === true,
      noCache: view.meta?.noCache === true,
    } as TagView;
  }

  // actions
  function addView(view: RouteLocationNormalized) {
    // hide redirect
    if (view.path.startsWith('/redirect')) return;

    // add visitedView
    const o = visitedViews.value.find((a) => a.path === view.path);
    if (o && o.fullPath != view.fullPath) {
      o.query = view.query;
      o.fullPath = view.fullPath;
    }
    if (o === undefined) {
      const newTag: TagView = createTagView(view);
      if (newTag.affix) {
        const index = visitedViews.value.filter((a) => a.affix)?.length;
        visitedViews.value.splice(index, 0, newTag);
      } else {
        visitedViews.value.push(newTag);
      }
    }

    // add cachedView
    const viewName = view.name as string;
    if (viewName && !cachedViews.value.includes(viewName) && view.meta?.noCache !== true) {
      cachedViews.value.push(viewName);
    }
  }

  function delCachedView(tag: TagView) {
    if (tag.name) {
      const index = cachedViews.value.indexOf(tag.name);
      if (index > -1) cachedViews.value.splice(index, 1);
    }
  }
  function delView(tag: TagView) {
    // del visitedView
    const index = visitedViews.value.findIndex((a) => a.path == tag.path);
    if (index > -1) visitedViews.value.splice(index, 1);

    // del cachedView
    delCachedView(tag);
  }

  function delOtherViews(tag: TagView) {
    // del visitedView
    visitedViews.value = visitedViews.value.filter((item) => {
      if (item.affix || item.path === tag.path) return true;
      else {
        delCachedView(item);
        return false;
      }
    });
  }

  function delAllViews() {
    visitedViews.value = visitedViews.value.filter((item) => {
      if (item.affix) return true;
      else {
        delCachedView(item);
        return false;
      }
    });
  }

  function delLeftViews(tag: TagView) {
    const currIndex = visitedViews.value.findIndex((v) => v.path === tag.path);
    visitedViews.value = visitedViews.value.filter((item, index) => {
      if (index >= currIndex || item.affix) return true;
      else {
        delCachedView(item);
        return false;
      }
    });
  }
  function delRightViews(tag: TagView) {
    const currIndex = visitedViews.value.findIndex((v) => v.path === tag.path);
    visitedViews.value = visitedViews.value.filter((item, index) => {
      if (index <= currIndex || item.affix) return true;
      else {
        delCachedView(item);
        return false;
      }
    });
  }

  function clearTagViews() {
    visitedViews.value = [];
    cachedViews.value = [];
  }

  return {
    visitedViews,
    cachedViews,
    addView,
    delView,
    delCachedView,
    delOtherViews,
    delAllViews,
    delLeftViews,
    delRightViews,
    clearTagViews,
  };
});
